home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Lib / lib-toolbox / MiniAEFrame.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  4.7 KB  |  176 lines

  1. """MiniAEFrame - A first stab at an AE Application framework.
  2. This framework is still work-in-progress, so do not rely on it remaining
  3. unchanged.
  4. """
  5.  
  6. import sys
  7. import traceback
  8. import MacOS
  9. import AE
  10. from AppleEvents import *
  11. import Evt
  12. from Events import *
  13. import Menu
  14. import Win
  15. from Windows import *
  16. import Qd
  17.  
  18. import aetools
  19. import EasyDialogs
  20.  
  21. kHighLevelEvent = 23                # Not defined anywhere for Python yet?
  22.  
  23. class MiniApplication:
  24.     """A minimal FrameWork.Application-like class"""
  25.  
  26.     def __init__(self):
  27.         self.quitting = 0
  28.         # Initialize menu
  29.         self.appleid = 1
  30.         self.quitid = 2
  31.         Menu.ClearMenuBar()
  32.         self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024")
  33.         applemenu.AppendMenu("All about cgitest...;(-")
  34.         applemenu.AppendResMenu('DRVR')
  35.         applemenu.InsertMenu(0)
  36.         self.quitmenu = Menu.NewMenu(self.quitid, "File")
  37.         self.quitmenu.AppendMenu("Quit")
  38.         self.quitmenu.InsertMenu(0)
  39.         Menu.DrawMenuBar()
  40.     
  41.     def __del__(self):
  42.         self.close()
  43.         
  44.     def close(self):
  45.         pass
  46.  
  47.     def mainloop(self, mask = everyEvent, timeout = 60*60):
  48.         while not self.quitting:
  49.             self.dooneevent(mask, timeout)
  50.             
  51.     def _quit(self):
  52.         self.quitting = 1
  53.     
  54.     def dooneevent(self, mask = everyEvent, timeout = 60*60):
  55.             got, event = Evt.WaitNextEvent(mask, timeout)
  56.             if got:
  57.                 self.lowlevelhandler(event)
  58.     
  59.     def lowlevelhandler(self, event):
  60.         what, message, when, where, modifiers = event
  61.         h, v = where
  62.         if what == kHighLevelEvent:
  63.             msg = "High Level Event: %s %s" % \
  64.                 (`code(message)`, `code(h | (v<<16))`)
  65.             try:
  66.                 AE.AEProcessAppleEvent(event)
  67.             except AE.Error, err:
  68.                 print 'AE error: ', err
  69.                 print 'in', msg
  70.                 traceback.print_exc()
  71.             return
  72.         elif what == keyDown:
  73.             c = chr(message & charCodeMask)
  74.             if c == '.' and modifiers & cmdKey:
  75.                 raise KeyboardInterrupt, "Command-period"
  76.         elif what == mouseDown:
  77.             partcode, window = Win.FindWindow(where)
  78.             if partcode == inMenuBar:
  79.                 result = Menu.MenuSelect(where)
  80.                 id = (result>>16) & 0xffff    # Hi word
  81.                 item = result & 0xffff        # Lo word
  82.                 if id == self.appleid:
  83.                     if item == 1:
  84.                         EasyDialogs.Message("cgitest - First cgi test")
  85.                         return
  86.                     elif item > 1:
  87.                         name = self.applemenu.GetItem(item)
  88.                         Qd.OpenDeskAcc(name)
  89.                         return
  90.                 if id == self.quitid and item == 1:
  91.                     print "Menu-requested QUIT"
  92.                     self.quitting = 1
  93.         # Anything not handled is passed to Python/SIOUX
  94.         MacOS.HandleEvent(event)
  95.         
  96. class AEServer:
  97.     
  98.     def __init__(self):
  99.         self.ae_handlers = {}
  100.         
  101.     def installaehandler(self, classe, type, callback):
  102.         AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
  103.         self.ae_handlers[(classe, type)] = callback
  104.     
  105.     def close(self):
  106.         for classe, type in self.ae_handlers.keys():
  107.             AE.AERemoveEventHandler(classe, type)
  108.             
  109.     def callback_wrapper(self, _request, _reply):
  110.         _parameters, _attributes = aetools.unpackevent(_request)
  111.         _class = _attributes['evcl'].type
  112.         _type = _attributes['evid'].type
  113.         
  114.         if self.ae_handlers.has_key((_class, _type)):
  115.             _function = self.ae_handlers[(_class, _type)]
  116.         elif self.ae_handlers.has_key((_class, '****')):
  117.             _function = self.ae_handlers[(_class, '****')]
  118.         elif self.ae_handlers.has_key(('****', '****')):
  119.             _function = self.ae_handlers[('****', '****')]
  120.         else:
  121.             raise 'Cannot happen: AE callback without handler', (_class, _type)
  122.         
  123.         # XXXX Do key-to-name mapping here
  124.         
  125.         _parameters['_attributes'] = _attributes
  126.         _parameters['_class'] = _class
  127.         _parameters['_type'] = _type
  128.         if _parameters.has_key('----'):
  129.             _object = _parameters['----']
  130.             del _parameters['----']
  131.             try:
  132.                 rv = apply(_function, (_object,), _parameters)
  133.             except TypeError, name:
  134.                 raise TypeError, ('AppleEvent handler misses formal keyword argument', _function, name)
  135.         else:
  136.             try:
  137.                 rv = apply(_function, (), _parameters)
  138.             except TypeError, name:
  139.                 raise TypeError, ('AppleEvent handler misses formal keyword argument', _function, name)
  140.         
  141.         if rv == None:
  142.             aetools.packevent(_reply, {})
  143.         else:
  144.             aetools.packevent(_reply, {'----':rv})
  145.             
  146. def code(x):
  147.     "Convert a long int to the 4-character code it really is"
  148.     s = ''
  149.     for i in range(4):
  150.         x, c = divmod(x, 256)
  151.         s = chr(c) + s
  152.     return s
  153.  
  154. class _Test(AEServer, MiniApplication):
  155.     """Mini test application, handles required events"""
  156.     
  157.     def __init__(self):
  158.         MiniApplication.__init__(self)
  159.         AEServer.__init__(self)
  160.         self.installaehandler('aevt', 'oapp', self.open_app)
  161.         self.installaehandler('aevt', 'quit', self.quit)
  162.         self.installaehandler('aevt', '****', self.other)
  163.         self.mainloop()
  164.  
  165.     def quit(self, **args):
  166.         self._quit()
  167.         
  168.     def open_app(self, **args):
  169.         pass
  170.         
  171.     def other(self, _object=None, _class=None, _type=None, **args):
  172.         print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
  173.         
  174. if __name__ == '__main__':
  175.     _Test()
  176.